package com.xbongbong.paas.controller.dingtalk;

import com.alibaba.dingtalk.openapi.exception.OApiException;
import com.alibaba.dingtalk.openapi.helper.AuthHelper;
import com.alibaba.dingtalk.openapi.helper.DingCoolAppHelper;
import com.alibaba.dingtalk.openapi.helper.Env;
import com.alibaba.dingtalk.openapi.helper.MiniMemberInfoHelper;
import com.alibaba.dingtalk.openapi.utils.aes.DingTalkEncryptException;
import com.alibaba.dingtalk.openapi.utils.aes.DingTalkEncryptor;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dingtalkim_1_0.models.GetSceneGroupInfoResponseBody;
import com.xbongbong.coolapp.BizManager;
import com.xbongbong.coolapp.service.CoolAppCardService;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.CompanyService;
import com.xbongbong.paas.service.async.EventChangeReceiveAsync;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.util.URLEncodeUtils;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.coolapp.callback.pojo.CardCallbackParamPojo;
import com.xbongbong.pro.coolapp.callback.pojo.CardCallbackPojo;
import com.xbongbong.pro.coolapp.pojo.dto.CoolAppUpdateCardDTO;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.thread.ThreadPoolBeanConfig;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.CoolAppCardDataEntity;
import com.xbongbong.saas.domain.entity.DingBundleEntity;
import com.xbongbong.saas.domain.entity.DingBundleUserEntity;
import com.xbongbong.saas.domain.entity.LikeEntity;
import com.xbongbong.saas.enums.BusinessCommentEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CustomerCommunicateEnum;
import com.xbongbong.saas.enums.mini.DingBundleStatusEnum;
import com.xbongbong.saas.enums.mini.DingBundleTypeEnum;
import com.xbongbong.saas.enums.mini.DingBundleUserOperateEnum;
import com.xbongbong.saas.model.CoolAppCardDataModel;
import com.xbongbong.saas.model.DingBundleModel;
import com.xbongbong.saas.model.DingBundleUserModel;
import com.xbongbong.saas.model.DingRobotManageModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.LikeModel;
import com.xbongbong.saas.service.EventChangeCustomerService;
import com.xbongbong.saas.service.LikeService;
import com.xbongbong.saas.service.SaasDetailTabService;
import com.xbongbong.sys.domain.entity.CompanyEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.CompanyModel;
import com.xbongbong.sys.model.UserModel;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;

/**
 * 接收事件回调，并进行相关逻辑处理
 * @author kaka
 */
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX + "/dingtalk")
public class EventChangeReceiveController {

	private static final Logger LOG = LoggerFactory.getLogger(EventChangeReceiveController.class);

	@Resource
	private AuthHelper authHelper;
	@Resource
	private CompanyModel companyModel;
	@Resource
	private CompanyService companyService;
	@Resource
	private UserModel userModel;
	@Resource
	private EventChangeCustomerService eventChangeCustomerService;
	@Resource
	private PaasRedisHelper paasRedisHelper;
	@Resource
	private DingBundleUserModel dingBundleUserModel;
	@Resource
	private DingBundleModel dingBundleModel;
	@Resource
	private DingRobotManageModel dingRobotManageModel;
	@Resource
	private MiniMemberInfoHelper miniMemberInfoHelper;
	@Resource
	private BizManager bizManager;
	@Resource
	private DingCoolAppHelper dingCoolAppHelper;
	@Resource
	private CoolAppCardDataModel coolAppCardDataModel;
	@Resource
	private LikeService likeService;
	@Resource
	private LikeModel likeModel;
	@Resource
	private CoolAppCardService coolAppCardService;
	@Resource
	private PaasFormModel paasFormModel;
	@Resource
	private SaasDetailTabService saasDetailTabService;
	@Resource
	private ThreadPoolBeanConfig threadPoolBeanConfig;
	@Resource
	private IndexTypeModel indexTypeModel;
	@Resource
	private EsHelper esHelper;
	@Resource
	private EventChangeReceiveAsync eventChangeReceiveAsync;

	/**
	 * 接收钉钉服务器的事件回调数据
	 */
	@ResponseBody
	@RequestMapping("/eventReceive")
	public String eventReceive(HttpServletRequest request)throws Exception {
	   /* url中的签名**/
       String msgSignature = request.getParameter("signature");
       /* url中的时间戳**/
       String timeStamp = request.getParameter("timestamp");
       /* url中的随机字符串**/
       String nonce = request.getParameter("nonce");

       /* post数据包数据中的加密数据**/
		StringBuilder sb = new StringBuilder();
		try (ServletInputStream sis =  request.getInputStream();
			 BufferedReader br = new BufferedReader(new InputStreamReader(sis))) {
			String line;
			while((line = br.readLine())!=null){
				sb.append(line);
			}
		} catch (Exception e) {
			LOG.error("eventReceive 流获取出错", e);
			//错误的回复
			return "";
		}
       JSONObject jsonEncrypt = JSONObject.parseObject(sb.toString());
       String encrypt = jsonEncrypt.getString("encrypt");

       /* 对encrypt进行解密**/
		DingTalkEncryptor dingTalkEncryptor;
		String plainText;
		try {
			//对于DingTalkEncryptor的第三个参数，ISV进行配置的时候传对应套件的SUITE_KEY，普通企业传Corpid
			dingTalkEncryptor = new DingTalkEncryptor(Env.TOKEN, Env.ENCODING_AES_KEY, Env.SUITE_KEY.length()>0 ? Env.SUITE_KEY : Env.CORP_ID);
			plainText = dingTalkEncryptor.getDecryptMsg(msgSignature, timeStamp, nonce, encrypt);
		} catch (DingTalkEncryptException e) {
			LOG.error("eventReceive 解密信息时出错", e);
			//错误的回复
			return "";
		}

       /* 对从encrypt解密出来的明文进行处理**/
		JSONObject plainTextJson = JSONObject.parseObject(plainText);

		LOG.info("通讯录事件回调: 回调信息内容 plainTextJson ===" + plainTextJson);

		/*
		 * EventType	事件类型，有九种，"user_add_org”, “user_modify_org”, “user_leave_org”,“org_admin_add”, “org_admin_remove”, “org_dept_create”, “org_dept_modify”, “org_dept_remove”, “org_remove”
		   TimeStamp	时间戳
           UserId	用户发生变更的userid列表
           DeptId	部门发生变更的DeptId列表
           CorpId	发生通讯录变更的企业
		 */
		String eventType = plainTextJson.getString("EventType");
		//公司ID应该每次都会传回,除了check_url
		final String corpId = plainTextJson.getString("CorpId");
		final String openConversationId = plainTextJson.getString("OpenConversationId");
		final String deptIds;
		final String userIds;
		final String operatorId;
		// 添加酷应用安装卸载事件
		if(!Objects.equals(eventType, "check_url") && !Objects.equals(eventType, "im_cool_app_install") && !Objects.equals(eventType, "im_cool_app_uninstall")) {
			if (StringUtil.isNotEmpty(corpId)) {
				long feeEndTime = companyService.getFeeEndTime(corpId);
				//到期时间已过期7天以上，或者到期时间超过30年（个人试用/免费版本），视为无效回调
				if (feeEndTime - DateTimeUtil.getInt() < -604800L ||
						feeEndTime - DateTimeUtil.getInt() > 946080000) {
					LOG.info("corpId: " + corpId + " 公司已超期或无效回调，已跳过");
					return getSuccessReturnStr(dingTalkEncryptor, timeStamp, nonce);
				}
			}
		}
		//更新持久吗
		String permanent_code = companyService.getPermanentCode(corpId);

		if(StringUtil.isEmpty(permanent_code)) {
			//有三家公司没有持久码，回调不处理了
			return getSuccessReturnStr(dingTalkEncryptor, timeStamp, nonce);
		}

		//获取accessToken
		final String accessToken;
		if(!Objects.equals(eventType, "check_url")) {
			try {
				accessToken = authHelper.getAccessToken(corpId);
			} catch (OApiException e) {
				LOG.error("回调获取accessToken时出错：", e);
				if(e.getErrCode() == 40079) {
					//可能出现了已经解绑的公司还有回调
					return getSuccessReturnStr(dingTalkEncryptor, timeStamp, nonce);
				} else {
					//错误的回复
					return "";
				}
			}
		} else {
			//只有在check_url的时候可能为null
			accessToken = null;
		}

		switch (eventType){
		case "user_add_org":
			LOG.info("收到 org_user_add 回调");
			userIds =  plainTextJson.getString("UserId");
			// 异步起线程执行逻辑
			eventChangeReceiveAsync.orgSaveUser(accessToken, corpId, userIds, true);

			break;
		case "user_modify_org":
			LOG.info("收到 org_user_modify 回调");
			userIds =  plainTextJson.getString("UserId");
			/*
			钉钉可能会在极小间隔100ms以内，甚至几乎同时推送相同信息，本处做兼容处理。
			 */
			String redisKey = corpId + "_" + userIds;
			boolean fstMsg = paasRedisHelper.checkConcurrentLock(RedisPrefixConstant.DD_EVENT_USER_MODIFY_ORG_LOCK, redisKey, 2, true);
			if (!fstMsg) {
				// 2秒内重复消息忽略
				break;
			}

			eventChangeReceiveAsync.orgSaveUser(accessToken, corpId, userIds, true);
			break;
		case "user_leave_org":
			LOG.info("收到 org_user_leave 回调");
			userIds =  plainTextJson.getString("UserId");
			try {
				// 异步执行逻辑
				eventChangeCustomerService.orgUserLeave(accessToken, corpId, userIds);
			} catch(Exception e) {
				LOG.error("user_leave_org orgUserLeave方法执行出错", e);
			}
			break;
		case "org_admin_add":
			LOG.info("收到 org_admin_add 回调");
			userIds =  plainTextJson.getString("UserId");
			try {
				orgadminChange(accessToken, corpId, userIds, 1);
			} catch(Exception e) {
				LOG.error("org_admin_add orgadminChange方法执行出错", e);
			}
			break;
		case "org_admin_remove":
			LOG.info("收到 org_admin_remove 回调");
			userIds =  plainTextJson.getString("UserId");
			try {
				orgadminChange(accessToken, corpId, userIds, 0);
			} catch(Exception e) {
				LOG.error("org_admin_remove orgadminChange方法执行出错", e);
			}
			break;
		case "org_dept_create":
			deptIds = plainTextJson.getString("DeptId");
			try {
				// 异步起线程
				eventChangeReceiveAsync.orgDeptChange(accessToken, corpId, deptIds);
			} catch(Exception e) {
				LOG.error("org_dept_create orgDeptChange方法执行出错", e);
			}
			LOG.info("收到 org_dept_create 回调");
			break;
		case "org_dept_modify":
			deptIds = plainTextJson.getString("DeptId");
			/*
			 * 目前部门修改主管的时候不会将修改的主管UserId列表回调 TODO 咨询下钉钉能否修改
			 */
//			userIds =  plainTextJson.getString("UserId");
			try {
				// 异步起线程
				eventChangeReceiveAsync.orgDeptChange(accessToken, corpId, deptIds);
			} catch(Exception e) {
				LOG.error("org_dept_modify orgDeptChange方法执行出错", e);
			}
			LOG.info("收到 org_dept_modify 回调");
			break;
		case "org_dept_remove":
			deptIds = plainTextJson.getString("DeptId");

			LOG.info("收到 org_dept_remove 回调");
			try {
				// 异步起线程
				eventChangeReceiveAsync.orgDeptRemove(corpId, deptIds);
			} catch(Exception e) {
				LOG.error("org_dept_remove orgDeptRemove方法执行出错", e);
			}

			break;
		case "org_remove":
			try {
				orgRemove(corpId);
			} catch(Exception e) {
				LOG.error("org_remove orgRemove方法执行出错", e);
			}
			LOG.info("收到 org_remove 回调");
			break;
		case "check_url":
			/*
			 * check_url，表明注册事件钉钉已收到，
			 * 最后返回success
			 */
			LOG.info("收到 check_url 回调");
			break;
		case "chat_add_member":
			/**
			 * 群会话添加人员
			 * {"Operator":"manager2546","OpenConversationId":"cidjmcGrYqUb87zm346GJlwZg==","CorpId":"dingf8e5f52a6b857a3aa39a90f97fcb1e09","EventType":"chat_add_member","UserId":["0249402125828407"],"TimeStamp":1599706504544,"ChatId":"chatf21278aba6c02901aea9c2153829d31b"}
			 */
			if (Objects.equals(corpId,"ding8bbfee4c40974e1e35c2f4657eb6378f")){
				LOG.info("-------plainTextJson:{}",plainTextJson);
			}
			JSONArray addUserIdArray = plainTextJson.getJSONArray("UserId");
			saveBundleUser(corpId, openConversationId, addUserIdArray, DingBundleUserOperateEnum.ADD_MEMBER);
			break;
		case "chat_remove_member":
			/**
			 * 群会话删除人员
			 * {"Operator":"manager2546","OpenConversationId":"cidjmcGrYqUb87zm346GJlwZg==","CorpId":"dingf8e5f52a6b857a3aa39a90f97fcb1e09","EventType":"chat_remove_member","UserId":["0249402125828407"],"TimeStamp":1599706625745,"ChatId":"chatf21278aba6c02901aea9c2153829d31b"}
			 */
			JSONArray deleteUserIdArray = plainTextJson.getJSONArray("UserId");
			saveBundleUser(corpId, openConversationId, deleteUserIdArray, DingBundleUserOperateEnum.DELETE_MEMBER);
			break;
		case "chat_quit":
			/**
			 * 群会话用户主动退群
			 * {"Operator":"manager2546","OpenConversationId":"cidjmcGrYqUb87zm346GJlwZg==","CorpId":"dingf8e5f52a6b857a3aa39a90f97fcb1e09","EventType":"chat_quit","TimeStamp":1599706874295,"ChatId":"chatf21278aba6c02901aea9c2153829d31b"}
			 */
			String deleteUserId = plainTextJson.getString("Operator");
			deleteUserIdArray = new JSONArray();
			deleteUserIdArray.add(deleteUserId);
			saveBundleUser(corpId, openConversationId, deleteUserIdArray, DingBundleUserOperateEnum.DELETE_MEMBER);
			break;
		case "chat_update_owner":
			/**
			 * 群会话更换群主
			 * {"Operator":"manager2546","OpenConversationId":"cidjmcGrYqUb87zm346GJlwZg==","Owner":"262664602823432266","CorpId":"dingf8e5f52a6b857a3aa39a90f97fcb1e09","EventType":"chat_update_owner","TimeStamp":1599706798943,"ChatId":"chatf21278aba6c02901aea9c2153829d31b"}
			 */
			String ownerId = plainTextJson.getString("Owner");
			updateBundleUserOwner(corpId, openConversationId, ownerId);
			break;
		case "chat_update_title":
			/**
			 * 群会话更换群名称
			 * {"Operator":"manager2546","OpenConversationId":"cidjmcGrYqUb87zm346GJlwZg==","CorpId":"dingf8e5f52a6b857a3aa39a90f97fcb1e09","EventType":"chat_update_title","Title":"第一个群通过接口创建1一","TimeStamp":1599706724805,"ChatId":"chatf21278aba6c02901aea9c2153829d31b"}
			 */
			String title = plainTextJson.getString("Title");
			updateBundleTitle(corpId, openConversationId, title);
			break;
		case "chat_disband":
			/**
			 * 群会话解散群
			 * {"Operator":"262664602823432266","OpenConversationId":"cidjmcGrYqUb87zm346GJlwZg==","CorpId":"dingf8e5f52a6b857a3aa39a90f97fcb1e09","EventType":"chat_disband","TimeStamp":1599706934616,"ChatId":"chatf21278aba6c02901aea9c2153829d31b"}
			 */
            Long TimeStamp = plainTextJson.getLongValue("TimeStamp");
			disbandBundle(corpId, openConversationId, TimeStamp);
			break;
		case "chat_template_change":
			/**
			 * 群模版启用/停用
			 * status：on：群模板启用，off：群模板停用
			 * {"Status":"on","Operator":"manager2546","ChangedTimeStamp":1604475115916,"OpenConversationId":"cid6tYJUTOcxG6xWKedavgWaQ==","CorpId":"dingf8e5f52a6b857a3aa39a90f
			 * 97fcb1e09","EventType":"chat_template_change","TimeStamp":1604475115926,"TemplateId":"63d69069-21f5-4091-ba1c-69bc91a08342"}
			 */
			String status = plainTextJson.getString("Status");
			chatTemplateChange(accessToken,corpId,openConversationId,status);
			break;
		case "im_cool_app_install":
			/**
			 * 启用群扩展应用事件
			 * {
			 *   "Operator": "01153741102xxxx",
			 *   "OpenConversationCorpId": "ding241f334c339e175b35c2f4657exxxxxx",
			 *   "OperateTime": "1650879464844",
			 *   "OpenConversationId": "cidAB41scvyrrMuKvpzxxxxxxx",
			 *   "CorpId": "ding241f334c339e175b35c2f4657exxxxxx",
			 *   "EventType": "im_cool_app_install",
			 *   "EventTime": 1650879464844,
			 *   "CoolAppCode": "COOLAPP-1-101B2DF7EFB1210481xxxxxB",
			 *   "RobotCode": "ding6nhzgndy3eyxxxxx",
			 *   "BizId": "08518bdbc0001bad7bafe643b0cf0c90"
			 * }
			 */
			operatorId = plainTextJson.getString("Operator");
			String coolAppCode = plainTextJson.getString("CoolAppCode");
			String robotCode = plainTextJson.getString("RobotCode");
			coolAppInstall(accessToken, corpId, openConversationId, operatorId, coolAppCode, robotCode);
			// 发送欢迎语卡片
			sendWelcomeCard(accessToken, corpId, openConversationId, robotCode);
			break;
		case "im_cool_app_uninstall":
			/**
			 * 卸载群扩展应用事件
			 * {
			 *   "Operator": "01153741102xxxx",
			 *   "OpenConversationCorpId": "ding241f334c339e175b35c2f4657exxxxxx",
			 *   "OperateTime": "1650878307670",
			 *   "OpenConversationId": "cidAB41scvyrrMuKvpzxxxxxxx==",
			 *   "CorpId": "ding241f334c339e175b35c2f4657exxxxxx",
			 *   "EventType": "im_cool_app_uninstall",
			 *   "EventTime": 1650878307670,
			 *   "CoolAppCode": "COOLAPP-1-101B2DF7EFB1210481xxxxxB",
			 *   "RobotCode": "ding6nhzgndy3eyxxxxx",
			 *   "BizId": "c16eb6123d69c36ae959e44f51e90524"
			 * }
			 */
			operatorId = plainTextJson.getString("Operator");
			coolAppUninstall(corpId, openConversationId, operatorId);
			break;
		default :
			break;
		}

       /* 对返回信息进行加密**/
		long timeStampLong = Long.parseLong(timeStamp);
		Map<String,String> jsonMap = null;
		try {
			jsonMap = dingTalkEncryptor.getEncryptedMap("success", timeStampLong, nonce);
		} catch (DingTalkEncryptException e) {
			LOG.error("构造eventReceive返回值出错", e);
		}
		JSONObject json = new JSONObject();
		json.putAll(jsonMap);

		LOG.info("eventReceive return");
		return json.toString();
	}


	/**
	 * 点赞回调
	 *
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping("/interactiveCardReceive/cardLike")
	public String cardLike(HttpServletRequest request) throws Exception {

		StringBuilder sb = new StringBuilder();
		try (ServletInputStream sis =  request.getInputStream();
			 BufferedReader br = new BufferedReader(new InputStreamReader(sis))) {
			String line;
			while((line = br.readLine())!=null){
				sb.append(line);
			}
		} catch (Exception e) {
			LOG.error("interactiveCardReceive/cardLike 流获取出错", e);
			//错误的回复
			return "";
		}
		// 参数值中（+）处理
		String paramStr = URLEncodeUtils.decodeURL(sb.toString()).replaceAll(" ", "+");
		JSONObject paramJson = JSONObject.parseObject(paramStr);
		CardCallbackPojo cardCallbackDTO = paramJson.toJavaObject(CardCallbackPojo.class);
		if (cardCallbackDTO == null) {
			return "";
		}
		JSONObject contentJson = JsonHelperUtil.parseObject(cardCallbackDTO.getContent());
		JSONObject cardPrivateData = contentJson.getJSONObject("cardPrivateData");
		if (cardPrivateData == null) {
			return "";
		}
		CardCallbackParamPojo paramPojo = cardPrivateData.getObject("params", CardCallbackParamPojo.class);
		if (paramPojo == null) {
			return "";
		}

		String corpid = cardCallbackDTO.getCorpId();
		String userId = cardCallbackDTO.getUserId();
		Long appId = paramPojo.getAppId();
		Long dataId = paramPojo.getDataId();
		Integer businessType = paramPojo.getBusinessType();
		BusinessCommentEnum businessCommentEnum = BusinessCommentEnum.getByBusinessType(businessType);
		if (businessCommentEnum == null) {
			return "";
		}

		// 员工不在销帮帮系统内，不能点赞
		UserEntity userEntity = userModel.getByKey(userId, corpid);
		if (userEntity == null) {
			return "";
		}

		// 调用点赞方法
		try {
			boolean ifILike = likeService.getIfLike(corpid, businessCommentEnum.getCode(), appId, dataId, userId);
			if (!ifILike) {
				LikeEntity likeEntity = new LikeEntity();
				likeEntity.setCorpid(corpid);
				likeEntity.setAppId(appId);
				likeEntity.setRefId(dataId);
				likeEntity.setUserId(userEntity.getUserId());
				likeEntity.setUserName(userEntity.getName());
				likeEntity.setUserAvatar(userEntity.getAvatar());
				likeEntity.setType(businessCommentEnum.getCode());
				likeModel.save(likeEntity);
			}
		} catch (XbbException e) {
			return "";
		}

		// 更新卡片信息
		try {
			UserVO userVO = userModel.getUserVO(corpid, userId, true, true);
			CoolAppUpdateCardDTO coolAppUpdateCardDTO = new CoolAppUpdateCardDTO(corpid, userId, userVO, PlatFormEnum.INTERNAL.getValue(), appId, null,
					SaasMarkEnum.SAAS.getCode(), businessType, dataId, cardCallbackDTO.getOpenConversationId(), cardCallbackDTO.getOutTrackId());
			coolAppCardService.updateCard(coolAppUpdateCardDTO);
		} catch (XbbException e) {
			LOG.error("更新卡片失败！", e);
		}

		return "success";
	}

	/**
	 * 关闭吊顶卡片回调
	 *
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping("/interactiveCardReceive/closeTopCard")
	public String closeTopCard( HttpServletRequest request) throws Exception {

		StringBuilder sb = new StringBuilder();
		try (ServletInputStream sis =  request.getInputStream();
			 BufferedReader br = new BufferedReader(new InputStreamReader(sis))) {
			String line;
			while((line = br.readLine())!=null){
				sb.append(line);
			}
		} catch (Exception e) {
			LOG.error("interactiveCardReceive/closeTopCard 流获取出错", e);
			//错误的回复
			return "";
		}
		JSONObject paramJson = JSONObject.parseObject(sb.toString());

		// 关闭吊顶卡片入参
		CardCallbackPojo cardCallbackDTO = paramJson.toJavaObject(CardCallbackPojo.class);
		// 关闭卡片
		String accessToken;
		try {
			accessToken = authHelper.getAccessToken(cardCallbackDTO.getCorpId());
		} catch (OApiException e) {
			LOG.error("回调获取accessToken时出错：", e);
			accessToken = null;
		}
		if (accessToken == null) {
			return "";
		}
		// 卡片数据
		CoolAppCardDataEntity cardDataEntity = coolAppCardDataModel.getByCardBizId(cardCallbackDTO.getCorpId(), cardCallbackDTO.getOutTrackId());
		if (cardDataEntity == null) {
			return "";
		}
		bizManager.closeTopCard(accessToken, cardDataEntity, null);

		return "success";
	}

	/**
	 * 返回成功信息
	 * @param dingTalkEncryptor
	 * @param timeStamp
	 * @param nonce
	 * @return
	 * kaka
	 * 2017年1月3日 上午9:54:11
	 */
	private String getSuccessReturnStr(DingTalkEncryptor dingTalkEncryptor, String timeStamp, String nonce) {
		/* 对返回信息进行加密**/
		long timeStampLong = Long.parseLong(timeStamp);
		Map<String,String> jsonMap = null;
		try {
			jsonMap = dingTalkEncryptor.getEncryptedMap("success", timeStampLong, nonce);
		} catch (DingTalkEncryptException e) {
			LOG.error("EventChangeReceiveController.getSuccessReturnStr DingTalkEncryptException", e);
		}
		JSONObject json = new JSONObject();
		json.putAll(jsonMap);

		return json.toString();
	}

	/**
	 * 收到员工被添加为管理员或删除管理员的处理
	 * 对应 org_admin_add & org_admin_remove
	 * @param accessToken accessToken
	 * @param corpId 公司id
	 * @param userIds 用户userId，可能是多个
	 * @param addOrRemove 1表示添加管理员，0表示删除管理员
	 */
	private void orgadminChange(String accessToken, String corpId, String userIds, int addOrRemove) {
		//钉钉管理员添加删除，我们不响应该回调
	}

	/**
	 * 公司解散收到的回调信息
	 * @param corpId
	 */
	private void orgRemove(String corpId) throws XbbException {
		CompanyEntity company = companyModel.getByKey(corpId);
		if(company != null) {
			//将公司设为解除绑定，且删除状态
			company.setDel(1);
			company.setStatus(-1);

			companyModel.update(company);
		}
	}

	private void updateBundleUserOwner(String corpid, String openConversationId, String ownerId) throws XbbException {
		DingBundleEntity dingBundleEntity = dingBundleModel.getByType(corpid, openConversationId, DingBundleTypeEnum.SALES_GROUP.getCode());
		if ( Objects.isNull(dingBundleEntity) || Objects.equals(dingBundleEntity.getStatus(), DingBundleStatusEnum.DISMISS.getCode()) ) {
			return;
		}
		String oldOwnerId = dingBundleEntity.getOwnerId();
		UserEntity userEntity = userModel.getByKey(ownerId, corpid);
		dingBundleEntity.setOwnerId(ownerId);
		dingBundleEntity.setName(userEntity.getName());
		dingBundleEntity.setAvatar(userEntity.getAvatar());
		dingBundleModel.update(dingBundleEntity);
		
		Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
		param.put("corpid",corpid);
		param.put("openConversationId", openConversationId);
		param.put("userIdIn",Arrays.asList(ownerId,oldOwnerId));
		param.put("del",0);
		List<DingBundleUserEntity> dingBundleUserEntityList = dingBundleUserModel.findEntitys(param);
		dingBundleUserEntityList.forEach(dingBundleUserEntity -> {
			if ( Objects.equals(dingBundleUserEntity.getUserId(), oldOwnerId) ) {
				dingBundleUserEntity.setIdentity(2);
			} else if ( Objects.equals(dingBundleUserEntity.getUserId(), ownerId) ){
				dingBundleUserEntity.setIdentity(0);
			}
		});
		if ( CollectionsUtil.isNotEmpty(dingBundleUserEntityList) ) {
			dingBundleUserModel.updateBatch(dingBundleUserEntityList);
		}
	}
	
	private void updateBundleTitle(String corpid, String openConversationId, String title) throws XbbException{
		DingBundleEntity dingBundleEntity = dingBundleModel.getByType(corpid, openConversationId, DingBundleTypeEnum.SALES_GROUP.getCode());
		if(Objects.isNull(dingBundleEntity)){
			dingBundleEntity = dingBundleModel.getByType(corpid, openConversationId, DingBundleTypeEnum.COOL_APP.getCode());
		}
		if ( Objects.isNull(dingBundleEntity) || Objects.equals(dingBundleEntity.getStatus(), DingBundleStatusEnum.DISMISS.getCode()) ) {
			return;
		}
		dingBundleEntity.setTitle(title);
		dingBundleModel.update(dingBundleEntity);
	}
	
	private void chatTemplateChange(String accessToken, String corpid, String openConversationId,String statusStr) throws XbbException {
		DingBundleEntity entity = dingBundleModel.getByType(corpid, openConversationId,DingBundleTypeEnum.SALES_GROUP.getCode(), null);
		Boolean insertFlag = false;
		Integer status = DingBundleStatusEnum.NORMAL.getCode();
		if ( Objects.nonNull(entity) ) {
			if ( Objects.equals(entity.getStatus(), DingBundleStatusEnum.DISMISS.getCode()) ) {
				return;
			}
			if ( Objects.equals(statusStr, "off") ) {
				status = DingBundleStatusEnum.DISABLE.getCode();
			}
		} else {
			entity = new DingBundleEntity();
			insertFlag = true;
		}
		JSONObject result = null;
		try {
			result = miniMemberInfoHelper.getGroupInfo(accessToken, openConversationId);
		} catch (OApiException e) {
			LOG.error("获取群信息失败", e);
			return;
		}
		
		String title = result.getString("title");
		String icon = result.getString("icon");
		String ownerUserId = result.getString("owner_staff_id");
		String name = null;
		String avatar = null;
		UserEntity userEntity = userModel.getByKey(ownerUserId, corpid);
		if ( Objects.nonNull(userEntity) ) {
			name = userEntity.getName();
			avatar = userEntity.getAvatar();
		}
		entity.setOpenConversationId(openConversationId);
		entity.setType(DingBundleTypeEnum.SALES_GROUP.getCode());
		entity.setStatus(status);
		entity.setCorpid(corpid);
		entity.setTitle(title);
		entity.setIcon(icon);
		entity.setOwnerId(ownerUserId);
		entity.setName(name);
		entity.setAvatar(avatar);
		if ( insertFlag ) {
			dingBundleModel.insert(entity);
		} else {
			dingBundleModel.update(entity);
		}
		
		
		Boolean hasMore = true;
		String cursor = "1";
		List<String> menberUserIds = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
		while (hasMore) {
			JSONObject jsonMember = null;
			try {
				jsonMember = miniMemberInfoHelper.getGroupMemberInfo(accessToken, openConversationId, cursor);
			} catch (OApiException e) {
				LOG.error("获取群成员信息失败", e);
				continue;
			}
			List<String> memberList = (List<String>) jsonMember.get("member_user_ids");
			menberUserIds.addAll(memberList);
			hasMore = jsonMember.getBoolean("has_more");
			cursor = jsonMember.getString("next_cursor");
		}
		if ( !insertFlag ) {
			Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
			param.put("corpid", corpid);
			param.put("del", 0);
			param.put("bundleId", entity.getId());
			List<DingBundleUserEntity> dingBundleUserEntityList = dingBundleUserModel.findEntitys(param);
			//不需要操作的用户
			List<String> noRemoveUserId = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
			//需要删除的用户
			List<String> needRemoveUserId = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
			//需要删除的用户
			List<Long> removeDataIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
			
			dingBundleUserEntityList.forEach(dingBundleUserEntity -> {
				String userId = dingBundleUserEntity.getUserId();
				if ( menberUserIds.contains(userId) ) {
					noRemoveUserId.add(userId);
				} else {
					needRemoveUserId.add(userId);
					removeDataIdIn.add(dingBundleUserEntity.getId());
				}
			});
			menberUserIds.removeAll(needRemoveUserId);
			menberUserIds.removeAll(noRemoveUserId);
			if ( CollectionsUtil.isNotEmpty(needRemoveUserId) ) {
				dingBundleUserModel.deleteByBundleAndUserIds(corpid, entity.getId(), needRemoveUserId);
			}
		}
		if ( CollectionsUtil.isNotEmpty(menberUserIds) ) {
			List<UserEntity> userEntityList = userModel.getByUserIdIn(corpid, menberUserIds, true);
			List<DingBundleUserEntity> addBundleUserList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
			for ( UserEntity user : userEntityList ) {
				DingBundleUserEntity dingBundleUserEntity = new DingBundleUserEntity(entity.getId(), corpid, openConversationId, user);
				if ( Objects.equals(user.getUserId(), entity.getOwnerId()) ) {
					dingBundleUserEntity.setIdentity(0);
				}
				addBundleUserList.add(dingBundleUserEntity);
			}
			if ( CollectionsUtil.isNotEmpty(addBundleUserList) ) {
				dingBundleUserModel.insertBatch(addBundleUserList);
			}
		}
		
	}
	
	private void disbandBundle(String corpid, String openConversationId,Long timeStamp) throws XbbException {
		//群解散
		DingBundleEntity entity = dingBundleModel.getByType(corpid, openConversationId, DingBundleTypeEnum.SALES_GROUP.getCode());
		if (Objects.isNull(entity)) {
			// 酷应用群
			entity = dingBundleModel.getByType(corpid, openConversationId, DingBundleTypeEnum.COOL_APP.getCode());
		}
		if (Objects.isNull(entity) || Objects.equals(entity.getStatus(), DingBundleStatusEnum.DISMISS.getCode()) ) {
			return;
		}
		entity.setUpdateTime(timeStamp);
		entity.setStatus(DingBundleStatusEnum.DISMISS.getCode());
		entity.setDel(1);
		dingBundleModel.update(entity);
		// 销售群
		if (Objects.equals(DingBundleTypeEnum.SALES_GROUP.getCode(), entity.getType())) {
			//群成员全部删除
			dingBundleUserModel.deleteByOpenConversationId(openConversationId,corpid);
			//群机器人设置全部删除
			dingRobotManageModel.deleteByOpenConversationId(openConversationId,corpid);
		}
	}

	private void saveBundleUser(String corpid, String openConversationId, JSONArray userArray, DingBundleUserOperateEnum operator) throws XbbException {
		DingBundleEntity dingBundleEntity = dingBundleModel.getByType(corpid, openConversationId, DingBundleTypeEnum.SALES_GROUP.getCode());
		if ( Objects.isNull(dingBundleEntity) || Objects.equals(dingBundleEntity.getStatus(), DingBundleStatusEnum.DISMISS.getCode()) ) {
			return;
		}
		String ownerId = dingBundleEntity.getOwnerId();
		switch (operator) {
			case ADD_MEMBER:
				if (Objects.equals(corpid,"ding8bbfee4c40974e1e35c2f4657eb6378f")){
					LOG.info("-------ADD_MEMBER");
				}
				Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
				param.put("corpid", corpid);
				param.put("openConversationId", openConversationId);
				param.put("del", 0);
				List<DingBundleUserEntity> dingBundleUserEntityList = dingBundleUserModel.findEntitys(param);
				Set<String> dingBundleUserIdSet = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
				if ( CollectionsUtil.isNotEmpty(dingBundleUserEntityList) ) {
					dingBundleUserEntityList.forEach(dingBundleUserEntity -> {
						dingBundleUserIdSet.add(dingBundleUserEntity.getUserId());
					});
				}
				List<String> addUserIds = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
				userArray.forEach(userIdObj -> {
					String userId = userIdObj.toString();
					if ( !dingBundleUserIdSet.contains(userId) ) {
						addUserIds.add(userId);
					}
				});
				if ( CollectionsUtil.isNotEmpty(addUserIds) ) {
					List<UserEntity> userEntityList = userModel.getByUserIdIn(corpid, addUserIds, true);
					List<DingBundleUserEntity> addBundleUserList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
					userEntityList.forEach(userEntity -> {
						DingBundleUserEntity dingBundleUserEntity = new DingBundleUserEntity(dingBundleEntity.getId(), corpid, openConversationId, userEntity);
						if ( Objects.equals(userEntity.getUserId(),ownerId) ) {
							dingBundleUserEntity.setIdentity(0);
						}
						addBundleUserList.add(dingBundleUserEntity);
					});
					if ( CollectionsUtil.isNotEmpty(addBundleUserList) ) {
						dingBundleUserModel.insertBatch(addBundleUserList);
						if (Objects.equals(corpid,"ding8bbfee4c40974e1e35c2f4657eb6378f")){
							LOG.info("-------ADD_MEMBER wancheng");
						}
					}
				}
				break;
			case DELETE_MEMBER:
				List<String> deleteUserIds = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
				userArray.forEach(userId -> {
					deleteUserIds.add(userId.toString());
				});
				if ( deleteUserIds.contains(ownerId) ) {
                    dingBundleEntity.setOwnerId("");
                    dingBundleEntity.setAvatar("");
                    dingBundleEntity.setName("");
                    dingBundleEntity.setUpdateTime(DateUtil.getNow());
                    dingBundleModel.update(dingBundleEntity);
                }
				dingBundleUserModel.deleteByBundleAndUserIds(corpid,dingBundleEntity.getId(), deleteUserIds);
				break;
			default:
				break;
		}

	}

	/***
	 * 安装酷应用
	 *
	 * @param accessToken
	 * @param corpid
	 * @param openConversationId
	 * @param operatorId
	 * @throws XbbException
	 * @return void
	 * @author hongxiao
	 * @date 2022-06-07 10:37
	 * @since
	 * @version
	 */
	private void coolAppInstall(String accessToken, String corpid, String openConversationId, String operatorId, String coolAppCode, String robotCode) throws XbbException{
		DingBundleEntity entity = dingBundleModel.getByType(corpid, openConversationId, DingBundleTypeEnum.COOL_APP.getCode());
		boolean insertFlag = false;
		if (Objects.isNull(entity)) {
			entity = new DingBundleEntity();
			String name = "";
			String avatar = "";
			String title = "";
			String icon = "";

			GetSceneGroupInfoResponseBody result = dingCoolAppHelper.getGroupInfo(accessToken, openConversationId, coolAppCode);
			if (Objects.nonNull(result)) {
				title = result.getTitle();
				icon = result.getIcon();
			}


			UserEntity userEntity = userModel.getByKey(operatorId, corpid);
			if ( Objects.nonNull(userEntity) ) {
				name = userEntity.getName();
				avatar = userEntity.getAvatar();
			}
			entity.setOpenConversationId(openConversationId);
			entity.setType(DingBundleTypeEnum.COOL_APP.getCode());
			entity.setCorpid(corpid);
			entity.setTitle(title);
			entity.setIcon(icon);
			entity.setOwnerId(operatorId);
			entity.setName(name);
			entity.setAvatar(avatar);

			insertFlag = true;
		}

		entity.setStatus(DingBundleStatusEnum.NORMAL.getCode());
		if ( insertFlag ) {
			dingBundleModel.insert(entity);
			// xbb线索/客户表单中对应客户写一条跟进记录
			writeCustomerCommunicate(corpid, openConversationId, operatorId);
		} else {
			dingBundleModel.update(entity);
		}

	}

	public void writeCustomerCommunicate(String corpid, String openConversationId, String operatorId) throws XbbException {
		Runnable runnable = () -> {
			Long formId = getXbbFormIdClue();
			String attr = getClueAttr();
			String xbbCorpid = getCorpId();
			UserVO userVO = getUserInfo(xbbCorpid, getUserId());
			CompanyEntity companyEntity = companyModel.getByKey(corpid);
			if (Objects.isNull(companyEntity)){
				LOG.info("-----------companyEntity:null");
				return;
			}
			UserEntity userEntity = userModel.getByKey(operatorId, corpid);
			if (Objects.isNull(userEntity)){
				LOG.info("-----------userEntity:null");
				return;
			}
			DingBundleEntity dingBundleEntity = dingBundleModel.getByOpenConversationId(corpid, openConversationId);
			if (Objects.isNull(dingBundleEntity)){
				LOG.info("-----------dingBundleEntity:null");
				return;
			}

			XbbAggregatedPage byEs = findByEs(attr, xbbCorpid, formId, corpid, XbbRefTypeEnum.CLUE.getCode());
			if (Objects.isNull(byEs)){
				LOG.error("-----------byEs is null");
				return;
			}
			List<PaasFormDataEntityExt> paasFormDataEntityList = byEs.getContent();
			// 线索表单搜不到该客户，继续搜索客户表单
			if (CollectionsUtil.isNotEmpty(paasFormDataEntityList)){
				PaasFormDataEntityExt paasFormDataEntityExt = paasFormDataEntityList.get(0);
				paasFormDataEntityExt.setBusinessType(XbbRefTypeEnum.CLUE.getCode());
				FormDataAddDTO formDataAddDTO = getCommunicateDTO(companyEntity, xbbCorpid, userVO, userEntity.getName(), formId, paasFormDataEntityExt, dingBundleEntity);
				// xb公司id
				JSONObject dataList = getCommunicateData(paasFormDataEntityExt.getId());
				formDataAddDTO.setDataList(dataList);
				try {
					saasDetailTabService.saveCustomerCommunicate(formDataAddDTO);
				} catch (XbbException e) {
					LOG.info("com.xbongbong.saas.service.SaasDetailTabService.saveCustomerCommunicate is error",e);
				}
			}
			// 如果客户表单里存在新增一条客户的跟进记录
			formId = getXbbFormIdCustomer();
			attr = getCustomerAttr();
			XbbAggregatedPage byEs2 = findByEs(attr, xbbCorpid, formId, corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
			if (Objects.isNull(byEs2)){
				LOG.error("-----------byPage is null");
				return;
			}
			List<PaasFormDataEntityExt> paasFormDataEntityList2 = byEs2.getContent();

			if (CollectionsUtil.isEmpty(paasFormDataEntityList2)){
				LOG.info("---------paasFormDataEntityList2 is null");
				return;
			}
			PaasFormDataEntityExt paasFormDataEntityExt2 = paasFormDataEntityList2.get(0);
			paasFormDataEntityExt2.setBusinessType(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
			FormDataAddDTO formDataAddDTO = getCommunicateDTO(companyEntity, xbbCorpid, userVO, userEntity.getName(), formId, paasFormDataEntityExt2, dingBundleEntity);
			JSONObject dataList = getCommunicateData(paasFormDataEntityExt2.getId());
			formDataAddDTO.setDataList(dataList);

			try {
				saasDetailTabService.saveCustomerCommunicate(formDataAddDTO);
			} catch (XbbException e) {
				LOG.info("com.xbongbong.saas.service.SaasDetailTabService.saveCustomerCommunicate is error",e);
			}
		};
		threadPoolBeanConfig.interactiveCardThreadPool().execute(runnable);
	}

	private XbbAggregatedPage findByEs(String attr, String xbbCorpid, Long formId, String corpid, int bussinessType){
		BoolQueryBuilder boolQueryBuilder = boolQuery();
		String esData = StringConstant.JSON_DATA + StringConstant.POINT;
		String keyword = StringConstant.POINT + StringConstant.KEY_WORD;
		boolQueryBuilder.filter(termQuery(ParameterConstant.CORPID + keyword, xbbCorpid));
		boolQueryBuilder.filter(termQuery(ParameterConstant.DEL, DelEnum.NORMAL.getDel()));
		boolQueryBuilder.filter(termQuery(ParameterConstant.FORMID, formId));
		boolQueryBuilder.filter(termQuery(esData + attr + keyword, corpid));
		XbbAggregatedPage byPage = null;
		try {
			IndexTypeEnum index = indexTypeModel.getIndexType(xbbCorpid, bussinessType, SaasMarkEnum.SAAS.getCode());
			byPage = esHelper.findByPage(index, boolQueryBuilder, PaasFormDataEntityExt.class, null, 1, 1, null);

		} catch (XbbException e) {
			LOG.error("------------",e);
		}
		return byPage;
	}

	/***
	 * 获取生成跟进记录的DTO
	 *
	 * @param companyEntity 当前公司
	 * @param xbbCorpid 销帮公司corpid
	 * @param userVO 销帮公司数据创建人
	 * @param operatorName 酷应用创建人
	 * @param formId 销帮公司客户或销售线索表单id
	 * @param dataEntityExt 销帮公司客户或销售线索数据
	 * @param dingBundleEntity 群实体
	 * @throws
	 * @return FormDataAddDTO
	 * @author hongxiao
	 * @date 2022-09-07 16:36
	 * @since
	 * @version
	 */
	private FormDataAddDTO getCommunicateDTO(CompanyEntity companyEntity, String xbbCorpid, UserVO userVO, String operatorName,
											 Long formId, PaasFormDataEntityExt dataEntityExt, DingBundleEntity dingBundleEntity) {
		FormDataAddDTO formDataAddDTO = new FormDataAddDTO();
		formDataAddDTO.setLoginUser(userVO);
		formDataAddDTO.setBusinessType(dataEntityExt.getBusinessType());
		// xb公司id
		formDataAddDTO.setCorpid(xbbCorpid);
		formDataAddDTO.setFormId(formId);
		formDataAddDTO.setMenuId(dataEntityExt.getMenuId());
		formDataAddDTO.setSaasMark(BasicConstant.ONE);
		formDataAddDTO.setDistributorMark(BasicConstant.ZERO);
		formDataAddDTO.setUserId(getUserId());
		formDataAddDTO.setPlatform(PlatFormEnum.INTERNAL.getValue());
		formDataAddDTO.setAppId(dataEntityExt.getAppId());
		JSONObject dataList = getCommunicateData(dataEntityExt.getId());
		formDataAddDTO.setDataList(dataList);
		SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo = new SaasNeedRedundantAttrPojo();
		// 某某公司（公司ID）的某某群（群ID），某某用户于XXXX年XX月XX日启用了客户管理酷应用

		String dataTime = DateTimeUtil.getString(DateTimeUtil.SDF);
		String memo = companyEntity.getCorpName()+"(" + companyEntity.getCorpid() + ")的群 "+ dingBundleEntity.getTitle() + " (" + dingBundleEntity.getOpenConversationId() +  ") ，"
				+ operatorName + " 于" + dataTime + " 启用了客户管理酷应用";
		saasNeedRedundantAttrPojo.setMemo(memo);
		LOG.info("----------businessType:{}",dataEntityExt.getBusinessType());
		saasNeedRedundantAttrPojo.setParentBusinessType(dataEntityExt.getBusinessType());
		saasNeedRedundantAttrPojo.setParentId(dataEntityExt.getId());
		formDataAddDTO.setSaasNeedRedundantAttrPoJo(saasNeedRedundantAttrPojo);
		formDataAddDTO.setSerialNo("");

		return formDataAddDTO;
	}

	/**
	 * 获取跟进记录的数据data
	 *
	 * @param dataId 客户或销售线索数据id
	 * @return
	 */
	private JSONObject getCommunicateData(Long dataId) {
		JSONObject data = new JSONObject();
		// 拼装data
		data.put(CustomerCommunicateEnum.COMMUNICATE_TIME.getAttr(), DateUtil.getInt());
		JSONObject customerName = new JSONObject();
		customerName.put("id",dataId);
		customerName.put("dataId",dataId);
		data.put(CustomerCommunicateEnum.CUSTOMER_NAME.getAttr(), customerName);
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("text","有效沟通");
		jsonObject.put("value","2");
		data.put("text_2", jsonObject);
		JSONObject jsonObject1 = new JSONObject();
		jsonObject1.put("text","网络拜访");
		jsonObject1.put("value","6");
		data.put(CustomerCommunicateEnum.TYPE.getAttr(), jsonObject1);
		JSONObject jsonObject2 = new JSONObject();
		jsonObject2.put("text","否");
		jsonObject2.put("value","a7b0a428-3c65-f30a-b5b6-c52aba1c2a9f");
		data.put("text_8", jsonObject2);

		return data;
	}

	public static String getClueAttr() {
		String projectName = ProBaseConfig.getProjectName();
		String attr = "";
		//区分正式环境与本地环境
		if (projectName.startsWith("xbbProTest2")) {
			// 测二QA周清清
			attr = "text_11";
		}else {
			// xbb公司id
			attr = "text_33";
		}
		return attr;
	}

	public static String getCustomerAttr() {
		String projectName = ProBaseConfig.getProjectName();
		String attr = "";
		//区分正式环境与本地环境
		if (projectName.startsWith("xbbProTest2")) {
			// 测二QA周清清
			attr = "text_24";
		}else {
			// xbb公司id
			attr = "text_28";
		}
		return attr;
	}

	public static String getCorpId() {
		String projectName = ProBaseConfig.getProjectName();
		String corpid = "";
		//区分正式环境与本地环境
		if (projectName.startsWith("xbbProTest2")) {
			// 测二QA周清清
			corpid = "ding51d0a413630fcca735c2f4657eb6378f";
		}else {
			// xbb公司id
			corpid = "dinge3fa697f86d461d2";
		}
		return corpid;
	}

	public static String getUserId() {
		String projectName = ProBaseConfig.getProjectName();
		String userId = "";
		//区分正式环境与本地环境
		if (projectName.startsWith("xbbProTest2")) {
			// 测二QA周清清
			userId = "385139392526159852";
		}else {
			// 会兵的用户id
			userId = "02415643151585";
		}
		return userId;
	}

	public Long getXbbFormIdClue(){
		String projectName = ProBaseConfig.getProjectName();
		Long formId = null;
		//区分正式环境与本地环境
		if (projectName.startsWith("xbbProTest2")) {
			// 钉钉测试2环境 公司测试QA周晴晴,线索表单
			formId = 15323L;
		} else {
			// 生产环境线索表单
			formId = 2795678L;
		}
		return formId;
	}

	public Long getXbbFormIdCustomer(){
		String projectName = ProBaseConfig.getProjectName();
		Long formId = null;
		//区分正式环境与本地环境
		if (projectName.startsWith("xbbProTest2")) {
			// 钉钉测试2环境 公司测试QA周晴晴,客户表单
			formId = 1692L;
		} else {
			// 生产环境客户表单
			formId = 572924L;
		}
		return formId;
	}

	public UserVO getUserInfo(String corpid, String userId){

		UserVO userVO = null;
		try {
			UserEntity user = userModel.getByKey(userId, corpid);

			if(user == null) {
				throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.USER_NOT_EXIST);
			}
			//用户信息
			userVO = new UserVO();
			BeanUtil.copyProperties(user, userVO);
			//用户复杂数据
			userModel.assembleUserVO(userVO, true);
		} catch (XbbException e) {
			LOG.error("com.xbongbong.paas.controller.dingtalk.EventChangeReceiveController.getUserInfo is error", e);
		} catch (Exception e) {
			LOG.error("com.xbongbong.paas.controller.dingtalk.EventChangeReceiveController.getUserInfo is error", e);
		}
		return userVO;
	}


	/***
	 * 卸载酷应用
	 *
	 * @param corpid
	 * @param openConversationId
	 * @param operatorId
	 *
	 * @author hongxiao
	 * @date 2022-06-07 10:36
	 * @since
	 * @version
	 */
	private void coolAppUninstall(String corpid, String openConversationId, String operatorId) {
		DingBundleEntity entity = dingBundleModel.getByType(corpid, openConversationId, DingBundleTypeEnum.COOL_APP.getCode());
		if (Objects.isNull(entity)) {
			return;
		}
		entity.setStatus(DingBundleStatusEnum.DISMISS.getCode());
		try {
			dingBundleModel.update(entity);
		} catch (Exception e) {
			LOG.error("关闭酷应用失败！", e);
		}
	}

	/**
	 * 酷应用发送欢迎语卡片
	 *
	 * @param accessToken
	 * @param corpid
	 * @param openConversationId
	 * @param robotCode
	 */
	private void sendWelcomeCard(String accessToken, String  corpid,String openConversationId, String robotCode) {
		Map<String,Object> map = new HashMap<>();
		map.put(StringConstant.CORPID, corpid);
		map.put("businessType", XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
		map.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
		map.put("enable",1);
		map.put("distributorMark", DistributorMarkEnum.OTHER.getCode());
		map.put("hidden", 0);
		List<PaasFormEntityExt> paasFormEntityExtList = paasFormModel.list(map);
		// 是否有体验按钮
		boolean isAddCustomer = CollectionsUtil.isNotEmpty(paasFormEntityExtList);
		Long appId = null;
		Long menuId = null;
		Long formId = null;
		if (CollectionsUtil.isNotEmpty(paasFormEntityExtList)) {
			PaasFormEntityExt paasFormEntityExt = paasFormEntityExtList.get(0);
			appId = paasFormEntityExt.getAppId();
			menuId = paasFormEntityExt.getMenuId();
			formId = paasFormEntityExt.getId();
		}

		bizManager.sendWelcomeCard(accessToken, corpid, openConversationId, robotCode, isAddCustomer, appId, menuId, formId);
	}
}
